package com.zpark.signup.exception;

import com.zpark.signup.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


/**
 * 全局异常处理
 */
//@RestControllerAdvice是一个用于统一处理控制器异常和返回结果的注解
@RestControllerAdvice(basePackages = "com.zpark.signup.controller")
// 使用@RestControllerAdvice注解，指定基础包名为"com.zpark.signup"
@Slf4j // 使用@Slf4j注解，简化日志记录的操作
public class GlobalException {


    // 定义一个处理方法参数验证失败的异常的方法
//    用于在Spring MVC应用程序中处理特定异常类型的方法
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    // 使用@ExceptionHandler注解，指定处理的异常类型为MethodArgumentNotValidException
    public R handleVaildException(MethodArgumentNotValidException e) { // 方法参数为MethodArgumentNotValidException类型，接收方法参数验证失败的异常对象

        log.error("数据校验出现问题：{}，异常类型：{}", e.getMessage(), e.getClass()); // 记录错误日志，包括异常信息和异常类型
        BindingResult bindingResult = e.getBindingResult(); // 获取绑定结果对象
        StringBuffer stringBuffer = new StringBuffer(); // 创建一个StringBuffer对象，用于拼接错误信息
        bindingResult.getFieldErrors().forEach(item -> { // 遍历每个字段错误
            //获取错误信息
            String message = item.getDefaultMessage();
            //获取错误的属性名字
            String field = item.getField();
            stringBuffer.append(field + ":" + message + " "); // 将字段名和错误信息拼接到StringBuffer对象中
        });
        return R.error(stringBuffer + ""); // 返回拼接后的错误信息字符串的R对象
    }


    // 定义一个处理所有类型异常的方法
    @ExceptionHandler(value = Throwable.class) // 使用@ExceptionHandler注解，指定处理的异常类型为Throwable（所有异常的父类）
    public R handleException(Throwable throwable) { // 方法参数为Throwable类型，接收所有异常对象

        log.error("错误", throwable); // 记录错误日志，包括异常信息
        return R.error("系统异常"); // 返回系统异常信息的R对象
    }

}